#include "TLine.h"
#include "TCanvas.h"
#include <iostream>
#include <fstream>

double** ReadMap(char*,int&);
double** ADCMapAdd(double**,int&,double,double,double,double);
void DrawSquare(double,double,double,double,int,int);
double max(double,double);
double min(double,double);

void MappingHitPos(char* filePath,double xLow,double xHigh,double yLow, double yHigh)
{   
	const double pi = 3.14159265;
	double windowHigh = 2.75;
	double windowLow = 1.15;
	double radiusHigh = (.6);
	double radiusLow = (sqrt(.02));
	int numberOfCrystals = 0;
	double** crystalInfo = ReadMap(filePath,numberOfCrystals);
	
	double xWindow = xHigh - xLow;
	double yWindow = yHigh - yLow;
	TCanvas* c1 = new TCanvas("canvas","ADCMap with Hits",800,yWindow/xWindow*800);
	(void)c1;

	for(int i=0 ;i<numberOfCrystals ;i++)
	{
		if(xLow<=crystalInfo[i][0]/100 && yLow<=crystalInfo[i][1]/100)
		{
			double xRel = (crystalInfo[i][0]/100-xLow)/xWindow;
			double yRel = (crystalInfo[i][1]/100-yLow)/yWindow;
			double xLengthRel = crystalInfo[i][2]/100/xWindow;
			double yLengthRel = crystalInfo[i][2]/100/yWindow;
			DrawSquare(xRel,yRel,xLengthRel,yLengthRel,crystalInfo[i][3],1);
		}
	}
        for(int i = 45 ; i<135 ; i+=3)
	{
		for(int j = 0 ; j<27 ; j++)
		{
				for(int n = 0 ; n<5 ; n++)
				{
					double z = (windowLow+(windowHigh-windowLow)/4*n);
					double maxPolar = max(z,radiusHigh);
					double minPolar = min(z,radiusLow);
					double polarStep = (maxPolar-minPolar)/27;
					double polar = minPolar+polarStep*(j+.5);
					DrawSquare((z*tan(polar)*cos(i*pi/180)-xLow)/xWindow,(z*tan(polar)*sin(i*pi/180)-yLow)/yWindow,0.001,0.001,1,4);
				}
		}
	}	
}   

void DrawSquare(double x,double y,double xlength,double ylength,int color,int width)
{
	xlength = xlength/2;
	ylength = ylength/2;
	double* xList = new double[5];
	double* yList = new double[5];
	xList[0]=x-xlength; xList[1]=x+xlength; xList[2]=x+xlength; xList[3]=x-xlength; xList[4]=x-xlength;
	yList[0]=y-ylength; yList[1]=y-ylength; yList[2]=y+ylength; yList[3]=y+ylength; yList[4]=y-ylength;
	TLine* bottom = new TLine(xList[0],yList[0],xList[1],yList[1]);
	TLine* sideOne = new TLine(xList[1],yList[1],xList[2],yList[2]);
	TLine* top = new TLine(xList[2],yList[2],xList[3],yList[3]);
	TLine* sideTwo = new TLine(xList[3],yList[3],xList[4],yList[4]);
	bottom->SetLineColor(color);
	bottom->SetLineWidth(width);
	bottom->Draw();
	sideOne->SetLineColor(color);
	sideOne->SetLineWidth(width);
	sideOne->Draw();
	top->SetLineColor(color);
	top->SetLineWidth(width);
	top->Draw();
	sideTwo->SetLineColor(color);
	sideTwo->SetLineWidth(width);
	sideTwo->Draw();

}

double max(double z,double r)
{
	return atan(r/z);
}

double min(double z,double r)
{
	return atan(r/z);
}

double** ADCMapAdd(double** map,int& count,double x,double y,double size,double color)
{
	double** newMap = new double*[count+1];

	for(int i = 0;i < count;i++) newMap[i] = map[i];
	delete map;

	newMap[count] = new double[4];

	newMap[count][0] = x;
	newMap[count][1] = y;
	newMap[count][2] = size;
	newMap[count][3] = color;

	count++;

	return newMap;
}

double** ReadMap(char* filePath,int& totalNum)
{
	int ADCMapCount = 0;
	double** ADCMap = new double*[ADCMapCount];

	std::ifstream file;
	file.open(filePath);

	char* number = new char[1024];
	for(int j = 0;j < 1024;j++) number[j] = ' ';
	int numberCount = 0;

	bool ADCFlag = true;
	int ADCNumber = 0;

	int color = 0;
	double size = 2.5;

	while(file.good())
	{
		char c = file.get();
		if(c == '\t')
		{
			if(ADCFlag)
			{
				ADCNumber = atoi(number);
				color = 1+ADCNumber%6;
				size  = 2.2 - (ADCNumber%5)*.425;
				ADCFlag = false;
			}
			else
			{
				int num = atoi(number);
				int i;
				int j;
				if(num < 3000)
				{
					j = num%48;
					i = (num-j)/48;
					ADCMap = ADCMapAdd(ADCMap,ADCMapCount,(i+.5-24)*2.5,(j+.5-24)*2.5,size,color);
				}
				else
				{
					j = (num-3000)%36;
					i = (num-3000-j)/36;
					ADCMap = ADCMapAdd(ADCMap,ADCMapCount,(i+.5-18)*5,(j+.5-18)*5,size,color);
				}
			}
			numberCount = 0;
			for(int j = 0;j < 1024;j++) number[j] = ' ';
			continue;
		}
		if(c == '\n')
		{
			if(!ADCFlag)
			{
				int num = atoi(number);
				int i;
				int j;
				if(num < 3000)
				{
					j = num%48;
					i = (num-j)/48;
					ADCMap = ADCMapAdd(ADCMap,ADCMapCount,(i+.5-24)*2.5,(j+.5-24)*2.5,size,color);
				}
				else
				{
					j = (num-3000)%36;
					i = (num-3000-j)/36;
					ADCMap = ADCMapAdd(ADCMap,ADCMapCount,(i+.5-18)*5,(j+.5-18)*5,size,color);
				}
			}
			ADCFlag = true;
			numberCount = 0;
			for(int j = 0;j < 1024;j++) number[j] = ' ';
			continue;
		}

		number[numberCount] = c;
		numberCount++;
	}

	delete number;

	totalNum = ADCMapCount;
	file.close();
	return ADCMap;
}
